﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace mevsukovGames
{
    enum Angle
    {
        Degree0 = 0,
        Degree90 = 1,
        Degree180 = 2,
        Degree270 = 3
    }

    abstract class Shape
    {
        public GameBlock FirstBlock {get; protected set;}
        public GameBlock SecondBlock {get; protected set;}
        public GameBlock ThirdBlock {get; protected set;}
        public GameBlock FourthBlock {get; protected set;}
        public Angle Position {get; protected set;}

        public abstract void RotateShape();

        public Shape(GameBlock first, GameBlock second, GameBlock third, GameBlock fourth)
        {
            FirstBlock = first;
            SecondBlock = second;
            ThirdBlock = third;
            FourthBlock = fourth;
            Position = Angle.Degree0;
        }

        public void MoveLeft(int step)
        {
            FirstBlock.MoveLeft(step);
            SecondBlock.MoveLeft(step);
            ThirdBlock.MoveLeft(step);
            FourthBlock.MoveLeft(step);
        }

        public void MoveRight(int step)
        {
            FirstBlock.MoveRight(step);
            SecondBlock.MoveRight(step);
            ThirdBlock.MoveRight(step);
            FourthBlock.MoveRight(step);
        }
        public void MoveDown(int step)
        {
            FirstBlock.MoveDown(step);
            SecondBlock.MoveDown(step);
            ThirdBlock.MoveDown(step);
            FourthBlock.MoveDown(step);
        }

        public void ChangePosition()
        {
            switch (this.Position)
            {
                case Angle.Degree0:
                    Position = Angle.Degree90;
                    break;
                case Angle.Degree90:
                    Position = Angle.Degree180;
                    break;
                case Angle.Degree180:
                    Position = Angle.Degree270;
                    break;
                case Angle.Degree270:
                    Position = Angle.Degree0;
                    break;     
            }
        }

    }

    class Square : Shape
    {
        //  [3][4]
        //  [1][2]
        public Square(GameBlock first, GameBlock second, GameBlock third, GameBlock fourth) :base(first,second,third,fourth)
        {

        }

        public override void RotateShape()
        {

        }


    }

    class Squiggle : Shape
    {
        // [3][4]
        //    [■][2]
        public Squiggle(GameBlock first, GameBlock second, GameBlock third, GameBlock fourth) 
            :base(first,second,third,fourth)
        {

        }

        public override void RotateShape()
        {
            switch (this.Position)
            {
                case Angle.Degree0:
                case Angle.Degree180:
                {
                    ChangePosition();
                    SecondBlock.BlockCoordinates.ChangeCoordinates(-1, -1);
                    ThirdBlock.BlockCoordinates.ChangeCoordinates(0, 2);
                    FourthBlock.BlockCoordinates.ChangeCoordinates(-1, 1);
                } break;
                case Angle.Degree90:
                case Angle.Degree270:
                {
                    ChangePosition();
                    SecondBlock.BlockCoordinates.ChangeCoordinates(1, 1);
                    ThirdBlock.BlockCoordinates.ChangeCoordinates(0, -2);
                    FourthBlock.BlockCoordinates.ChangeCoordinates(1, -1);
                } break;
            }
        }  
    }

    class ReverseSquigle : Shape
    {
        //       [3][4]
        //    [1][■]
        public ReverseSquigle(GameBlock first, GameBlock second, GameBlock third, GameBlock fourth) 
            :base(first,second,third,fourth)
        {

        }

        public override void RotateShape()
        {
            switch (this.Position)
            {
                case Angle.Degree0:
                case Angle.Degree180:
                {
                    ChangePosition();
                    FirstBlock.BlockCoordinates.ChangeCoordinates(1, 1);
                    ThirdBlock.BlockCoordinates.ChangeCoordinates(-1, 1);
                    FourthBlock.BlockCoordinates.ChangeCoordinates(-2, 0);
                }break;
                case Angle.Degree90:
                case Angle.Degree270:
                {
                    ChangePosition();
                    FirstBlock.BlockCoordinates.ChangeCoordinates(-1, -1);
                    ThirdBlock.BlockCoordinates.ChangeCoordinates(1, -1);
                    FourthBlock.BlockCoordinates.ChangeCoordinates(2, 0);
                } break;
            }
        }        
    }

    class LBlock : Shape
    {
        //    [4]
        //    [■]
        // [1][2]

        public LBlock(GameBlock first, GameBlock second, GameBlock third, GameBlock fourth)
            : base(first, second, third, fourth)
        {

        }

        public override void RotateShape()
        {
            switch (this.Position)
            {
                case Angle.Degree0:
                {
                    ChangePosition();
                    FirstBlock.BlockCoordinates.ChangeCoordinates(2, 0);
                    SecondBlock.BlockCoordinates.ChangeCoordinates(1, -1);
                    FourthBlock.BlockCoordinates.ChangeCoordinates(-1, 1);
                }break;
                case Angle.Degree90:
                {
                    ChangePosition();
                    FirstBlock.BlockCoordinates.ChangeCoordinates(0, -2);
                    SecondBlock.BlockCoordinates.ChangeCoordinates(-1,-1);
                    FourthBlock.BlockCoordinates.ChangeCoordinates(1,1);
                }break;

                case Angle.Degree180:
                {
                    ChangePosition();
                    FirstBlock.BlockCoordinates.ChangeCoordinates(-2,0);
                    SecondBlock.BlockCoordinates.ChangeCoordinates(-1,1);
                    FourthBlock.BlockCoordinates.ChangeCoordinates(1,-1);

                }break;

                case Angle.Degree270:
                {
                    ChangePosition();
                    FirstBlock.BlockCoordinates.ChangeCoordinates(0, 2);
                    SecondBlock.BlockCoordinates.ChangeCoordinates(1, 1);
                    FourthBlock.BlockCoordinates.ChangeCoordinates(-1, -1);
                } break;
            }
        }  
    }

    class RBlock : Shape
    {
        //  [4]
        //  [■]
        //  [1][2]

        public RBlock(GameBlock first, GameBlock second, GameBlock third, GameBlock fourth)
            : base(first, second, third, fourth)
        {

        }

        public override void RotateShape()
        {
            switch (this.Position)
            {
                case Angle.Degree0:
                {
                    ChangePosition();
                    FirstBlock.BlockCoordinates.ChangeCoordinates(1, -1);
                    SecondBlock.BlockCoordinates.ChangeCoordinates(0, -2);
                    FourthBlock.BlockCoordinates.ChangeCoordinates(-1, 1);
                }break;
                case Angle.Degree90:
                {
                    ChangePosition();
                    FirstBlock.BlockCoordinates.ChangeCoordinates(-1,-1);
                    SecondBlock.BlockCoordinates.ChangeCoordinates(-2,0);
                    FourthBlock.BlockCoordinates.ChangeCoordinates(1,1);
                }break;

                case Angle.Degree180:
                {
                    ChangePosition();
                    FirstBlock.BlockCoordinates.ChangeCoordinates(-1,1);
                    SecondBlock.BlockCoordinates.ChangeCoordinates(0,2);
                    FourthBlock.BlockCoordinates.ChangeCoordinates(1,-1);

                }break;

                case Angle.Degree270:
                {
                    ChangePosition();
                    FirstBlock.BlockCoordinates.ChangeCoordinates(1, 1);
                    SecondBlock.BlockCoordinates.ChangeCoordinates(2, 0);
                    FourthBlock.BlockCoordinates.ChangeCoordinates(-1, -1);
                } break;
            }
        }  
    }

    class TBlock : Shape
    {
        //    [4]
        // [1][■][3]

        public TBlock(GameBlock first, GameBlock second, GameBlock third, GameBlock fourth)
            : base(first, second, third, fourth)
        {

        }

        public override void RotateShape()
        {
            switch (this.Position)
            {
                case Angle.Degree0:
                {
                    ChangePosition();
                    FirstBlock.BlockCoordinates.ChangeCoordinates(1, 1);
                    ThirdBlock.BlockCoordinates.ChangeCoordinates(-1, -1);
                    FourthBlock.BlockCoordinates.ChangeCoordinates(-1, 1);
                }break;
                case Angle.Degree90:
                {
                    ChangePosition();
                    FirstBlock.BlockCoordinates.ChangeCoordinates(1,-1);
                    ThirdBlock.BlockCoordinates.ChangeCoordinates(-1, 1);
                    FourthBlock.BlockCoordinates.ChangeCoordinates(1,1);
                }break;

                case Angle.Degree180:
                {
                    ChangePosition();
                    FirstBlock.BlockCoordinates.ChangeCoordinates(-1,-1);
                    ThirdBlock.BlockCoordinates.ChangeCoordinates(1, 1);
                    FourthBlock.BlockCoordinates.ChangeCoordinates(1,-1);

                }break;

                case Angle.Degree270:
                {
                    ChangePosition();
                    FirstBlock.BlockCoordinates.ChangeCoordinates(-1, 1);
                    ThirdBlock .BlockCoordinates.ChangeCoordinates(1, -1);
                    FourthBlock.BlockCoordinates.ChangeCoordinates(-1, -1);
                } break;
            }
        } 
    }

    class LinePiece : Shape
    {
        // [4]
        // [3]
        // [■]
        // [1]      

        public LinePiece(GameBlock first, GameBlock second, GameBlock third, GameBlock fourth) 
            :base(first,second,third,fourth)
        {

        }

        public override void RotateShape()
        {
            switch (this.Position)
            {
                case Angle.Degree0:
                case Angle.Degree180:
                {
                    ChangePosition();
                    FirstBlock.BlockCoordinates.ChangeCoordinates(-1, -1);
                    ThirdBlock.BlockCoordinates.ChangeCoordinates(1, 1);
                    FourthBlock.BlockCoordinates.ChangeCoordinates(2, 2);
                } break;
                case Angle.Degree90:
                case Angle.Degree270:
                {
                    ChangePosition();
                    FirstBlock.BlockCoordinates.ChangeCoordinates(1, 1);
                    ThirdBlock.BlockCoordinates.ChangeCoordinates(-1, -1);
                    FourthBlock.BlockCoordinates.ChangeCoordinates(-2, -2);
                } break;
            }
        }  
    }
}
